<?php
namespace App\Http\Controllers\Admin;

use App\Enums\ResponseEnum;
use App\Http\Controllers\AdminController;
use App\Library\AttachmentTools;
use App\Models\System\Sites;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class UploadController extends AdminController
{
    private $storage = 'local';
    private $groupId = 0;
    private $config;

    private function init(Request $request)
    {
        abort_if(!extension_loaded('fileinfo'), ResponseEnum::SYSTEM_ERROR, 'fileinfo 拓展未开启');
        $this->config = Sites::GetPluginSet('uploadConfig');
        if (!empty($this->config['storage'])) {
            $this->storage = $this->config['storage'];
        }
        $this->groupId = $request->get('groupId');
    }

    public function uploadFile(Request $request)
    {
        $this->init($request);
        $request->validate(['file' => 'required|file']);
        $file = $request->file('file');
        //检查文件是否上传完成`
        if ($file->isValid()) {
            return $this->putFiles([
                'fileType' => $file->getMimeType(),
                'fileSize' => $file->getSize(),
                'fileName' => $file->getClientOriginalName(),
            ], $file);
        }
        return $this->error(ResponseEnum::SYSTEM_ERROR, $file->getErrorMessage());
    }

    public function networkImage(Request $request)
    {
        $this->init($request);
        $request->validate(['url' => 'required|active_url']);
        $url = trim($request->get('url'));
        try {
            $resp = (new \GuzzleHttp\Client(['verify' => false]))->get($url);
            if ($resp->getStatusCode() !== 200) {
                $this->throwBusinessException(ResponseEnum::UPLOAD_NETWORK_FILE_IS_NOT_ERROR);
            }
            $contentType = $resp->getHeader('content-type')[0];
            if (strpos($contentType, "image") !== 0) {
                $this->throwBusinessException(ResponseEnum::UPLOAD_NETWORK_FILE_FORMAT_ERROR);
            }
            return $this->putFiles([
                'fileType' => $contentType,
                'fileSize' => $resp->getHeader('Content-Length')[0],
                'fileName' => pathinfo(urldecode($url))['basename'],
            ], $resp->getBody()->getContents(), true);
        }catch (\GuzzleHttp\Exception\GuzzleException $e) {
            report($e);
        }
        return $this->error(ResponseEnum::SYSTEM_ERROR);
    }

    /**
     * @param $fileData
     * @param $fileContent
     * @param false $isNetwork
     * @return \Illuminate\Http\JsonResponse
     */
    private function putFiles($fileData, $fileContent, bool $isNetwork = false)
    {
        $fileType = $this->filesType($fileData["fileType"]);
        if (!in_array($fileType['ext'], $fileType["extensions"], true)) {
            $this->throwBusinessException(ResponseEnum::UPLOAD_FILE_FORMAT_ERROR, '仅支持 '.implode(',', $fileType["extensions"]).' 格式');
        }
        if ($fileData['fileSize'] > $fileType["maxSize"]*1024*1024) {
            $this->throwBusinessException(ResponseEnum::UPLOAD_FILE_MAXSIZE_ERROR, '上传文件大小限制 '.$fileType["maxSize"].'M');
        }
        $disk = AttachmentTools::getDisk($this->storage);
        $newPath = $fileType['type'].'s/'.date('Ymd');
        $isNetwork && $newPath .= '/'.Str::random(40).".".$fileType['ext'];
        if ($path = $disk->put($newPath, $fileContent)) {
            $imgPath = $isNetwork ? $newPath : $path;
            $attachment = AttachmentTools::createAttachment([
                "user_id" => $this->guard()->id(),
                "group_id" => $this->groupId ?? 0,
                "file_name" => $fileData['fileName'],
                "path" => $imgPath,
                "suffix" => $fileType['ext'],
                "type" => $fileData['fileType'],
                "storage" => $this->storage,
                "size" => $fileData['fileSize'],
            ]);
            return $this->succeed([
                'file_id' => $attachment['id'],
                'file_url' =>  $disk->url($imgPath),
                'file_name' => $fileData['fileName'],
                'file_path' => $imgPath,
            ]);
        }
        return $this->error(ResponseEnum::UPLOAD_FILE_ERROR);
    }

    /**
     * @param string $fileType
     * @return array
     */
    private function filesType(string $fileType): array
    {
        [$type, $ext] = explode('/', $fileType);
        if ($type === 'image') {
            return [
                "type" => $type,
                "ext" => $ext,
                "maxSize" => !empty($this->config['image_size']) ? (int)$this->config['image_size']/1024 : AttachmentTools::IMAGE_SIZE/1024,
                "extensions" => !empty($this->config['image_type']) ? (array)$this->config['image_type'] : AttachmentTools::IMAGE_TYPE
            ];
        }
        return [
            "type" => $type,
            "ext" => $ext,
            "maxSize" => !empty($this->config['file_size']) ? (int)$this->config['file_size']/1024 : AttachmentTools::FILE_SIZE/1024,
            "extensions" => !empty($this->config['file_type']) ? (array)$this->config['file_type'] : AttachmentTools::FILE_TYPE
        ];
    }

}
